<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AttendanceRule;
use App\Models\ClockInRecord;
use App\Models\AttendanceStatistic;
use App\Models\User;
use App\Models\Employee;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class AttendanceController extends Controller
{
    /**
     * 获取考勤规则列表
     */
    public function getRules(Request $request)
    {
        $query = AttendanceRule::query();

        // 搜索
        if ($request->has('search') && !empty($request->search)) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('code', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        // 类型筛选
        if ($request->has('type') && !empty($request->type)) {
            $query->where('type', $request->type);
        }

        // 状态筛选
        if ($request->has('status') && !empty($request->status)) {
            $query->where('status', $request->status);
        }

        $rules = $query->orderBy('sort_order')
                      ->orderBy('created_at', 'desc')
                      ->paginate($request->get('per_page', 15));

        return $this->success($rules, '获取考勤规则成功');
    }

    /**
     * 创建考勤规则
     */
    public function createRule(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:100|unique:attendance_rules',
            'type' => 'required|in:fixed,flexible,shift,no_check',
            'description' => 'nullable|string',
            'work_start_time' => 'nullable|date_format:H:i',
            'work_end_time' => 'nullable|date_format:H:i',
            'break_start_time' => 'nullable|date_format:H:i',
            'break_end_time' => 'nullable|date_format:H:i',
            'flexible_minutes' => 'nullable|integer|min:0',
            'allow_overtime' => 'boolean',
            'late_tolerance_minutes' => 'nullable|integer|min:0',
            'early_leave_tolerance_minutes' => 'nullable|integer|min:0',
            'allow_makeup' => 'boolean',
            'monthly_makeup_limit' => 'nullable|integer|min:0',
            'location_restriction' => 'nullable|in:none,fixed,area,gps',
            'status' => 'nullable|in:active,inactive',
            'sort_order' => 'nullable|integer|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => '验证失败',
                'errors' => $validator->errors()
            ], 422);
        }

        $rule = AttendanceRule::create($request->all());

        return response()->json([
            'success' => true,
            'message' => '创建考勤规则成功',
            'data' => $rule
        ]);
    }

    /**
     * 更新考勤规则
     */
    public function updateRule(Request $request, AttendanceRule $rule)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:100|unique:attendance_rules,code,' . $rule->id,
            'type' => 'required|in:fixed,flexible,shift,no_check',
            'description' => 'nullable|string',
            'work_start_time' => 'nullable|date_format:H:i',
            'work_end_time' => 'nullable|date_format:H:i',
            'break_start_time' => 'nullable|date_format:H:i',
            'break_end_time' => 'nullable|date_format:H:i',
            'flexible_minutes' => 'nullable|integer|min:0',
            'allow_overtime' => 'boolean',
            'late_tolerance_minutes' => 'nullable|integer|min:0',
            'early_leave_tolerance_minutes' => 'nullable|integer|min:0',
            'allow_makeup' => 'boolean',
            'monthly_makeup_limit' => 'nullable|integer|min:0',
            'location_restriction' => 'nullable|in:none,fixed,area,gps',
            'status' => 'nullable|in:active,inactive',
            'sort_order' => 'nullable|integer|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => '验证失败',
                'errors' => $validator->errors()
            ], 422);
        }

        $rule->update($request->all());

        return response()->json([
            'success' => true,
            'message' => '更新考勤规则成功',
            'data' => $rule
        ]);
    }

    /**
     * 删除考勤规则
     */
    public function deleteRule(AttendanceRule $rule)
    {
        // 检查是否有打卡记录使用此规则
        $hasRecords = ClockInRecord::where('attendance_rule_id', $rule->id)->exists();

        if ($hasRecords) {
            return response()->json([
                'success' => false,
                'message' => '该考勤规则已被使用，无法删除'
            ], 400);
        }

        $rule->delete();

        return response()->json([
            'success' => true,
            'message' => '删除考勤规则成功'
        ]);
    }

    /**
     * 获取用户的考勤规则
     */
    public function getUserRule(Request $request)
    {
        $user = $request->user();

        // 获取用户的考勤规则（根据部门、岗位、个人设置）
        $rule = $this->findUserAttendanceRule($user);

        if (!$rule) {
            return response()->json([
                'success' => true,
                'message' => '未找到适用的考勤规则',
                'data' => null
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => '获取考勤规则成功',
            'data' => $rule
        ]);
    }

    /**
     * 打卡
     */
    public function clockIn(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'type' => 'required|in:check_in,check_out,makeup',
            'clock_time' => 'nullable|date',
            'latitude' => 'nullable|numeric|between:-90,90',
            'longitude' => 'nullable|numeric|between:-180,180',
            'location_address' => 'nullable|string',
            'device_info' => 'nullable|string',
            'makeup_reason' => 'required_if:type,makeup|string',
            'source' => 'nullable|in:manual,machine,app,web,import',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => '验证失败',
                'errors' => $validator->errors()
            ], 422);
        }

        $user = $request->user();
        $clockTime = $request->clock_time ? Carbon::parse($request->clock_time) : now();

        DB::beginTransaction();
        try {
            // 获取用户适用的考勤规则
            $rule = $this->findUserAttendanceRule($user);

            // 如果是补卡，检查规则是否允许
            if ($request->type === 'makeup' && (!$rule || !$rule->allow_makeup)) {
                return response()->json([
                    'success' => false,
                    'message' => '该考勤规则不允许补卡'
                ], 400);
            }

            // 创建打卡记录
            $record = ClockInRecord::create([
                'user_id' => $user->id,
                'employee_id' => $user->employee?->id,
                'type' => $request->type,
                'clock_time' => $clockTime,
                'work_date' => $clockTime->toDateString(),
                'ip_address' => $request->ip(),
                'latitude' => $request->latitude,
                'longitude' => $request->longitude,
                'location_address' => $request->location_address,
                'device_info' => $request->device_info ?: $request->userAgent(),
                'attendance_rule_id' => $rule?->id,
                'is_makeup' => $request->type === 'makeup',
                'makeup_reason' => $request->makeup_reason,
                'source' => $request->source ?: 'web',
                'status' => $request->type === 'makeup' ? 'makeup_pending' : 'normal',
            ]);

            // 计算打卡状态
            if ($rule && $request->type !== 'makeup') {
                $this->calculateClockInStatus($record, $rule);
                $record->save();
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => '打卡成功',
                'data' => $record
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => '打卡失败：' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 获取打卡记录
     */
    public function getClockInRecords(Request $request)
    {
        $query = ClockInRecord::with(['user', 'employee', 'attendanceRule', 'approver']);

        // 用户筛选
        if ($request->has('user_id')) {
            $query->where('user_id', $request->user_id);
        }

        // 日期范围筛选
        if ($request->has('start_date') && $request->has('end_date')) {
            $query->byDateRange($request->start_date, $request->end_date);
        }

        // 类型筛选
        if ($request->has('type')) {
            $query->where('type', $request->type);
        }

        // 状态筛选
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        $records = $query->orderBy('clock_time', 'desc')
                         ->paginate($request->get('per_page', 15));

        return response()->json([
            'success' => true,
            'message' => '获取打卡记录成功',
            'data' => $records
        ]);
    }

    /**
     * 查找用户适用的考勤规则
     */
    private function findUserAttendanceRule(User $user)
    {
        // 优先查找个人规则
        $rule = AttendanceRule::active()
            ->where(function($query) use ($user) {
                $query->whereJsonContains('applicable_users', (string)$user->id);
            })
            ->first();

        if ($rule) {
            return $rule;
        }

        // 查找岗位规则
        if ($user->employee && $user->employee->position) {
            $rule = AttendanceRule::active()
                ->where(function($query) use ($user) {
                    $query->whereJsonContains('applicable_positions', (string)$user->employee->position->id);
                })
                ->first();

            if ($rule) {
                return $rule;
            }
        }

        // 查找部门规则
        if ($user->employee && $user->employee->department) {
            $rule = AttendanceRule::active()
                ->where(function($query) use ($user) {
                    $query->whereJsonContains('applicable_departments', (string)$user->employee->department->id);
                })
                ->first();

            if ($rule) {
                return $rule;
            }
        }

        // 返回默认规则（第一个活跃的固定时间规则）
        return AttendanceRule::active()
            ->where('type', 'fixed')
            ->orderBy('sort_order')
            ->first();
    }

    /**
     * 计算打卡状态
     */
    private function calculateClockInStatus(ClockInRecord $record, AttendanceRule $rule)
    {
        // 计算迟到
        if ($record->calculateLateStatus($rule)) {
            $record->status = 'late';
            $workStartTime = Carbon::parse($record->work_date . ' ' . $rule->work_start_time);
            $record->late_minutes = $record->clock_time->diffInMinutes($workStartTime);
        }

        // 计算早退
        if ($record->calculateEarlyStatus($rule)) {
            $record->status = 'early';
            $workEndTime = Carbon::parse($record->work_date . ' ' . $rule->work_end_time);
            $record->early_minutes = $workEndTime->diffInMinutes($record->clock_time);
        }
    }
}
